

package com.kimo.shop.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.kimo.shop.bean.app.dto.*;
import com.kimo.shop.bean.app.param.ChangeShopCartParam;
import com.kimo.shop.bean.app.param.OrderItemParam;
import com.kimo.shop.bean.app.param.ShopCartParam;
import com.kimo.shop.bean.enums.ProdType;
import com.kimo.shop.bean.event.ShopCartEvent;
import com.kimo.shop.bean.model.Basket;
import com.kimo.shop.bean.model.Product;
import com.kimo.shop.bean.model.ShopDetail;
import com.kimo.shop.bean.model.Sku;
import com.kimo.shop.common.config.Constant;
import com.kimo.shop.common.i18n.I18nMessage;
import com.kimo.shop.common.util.Arith;
import com.kimo.shop.common.util.CacheManagerUtil;
import com.kimo.shop.common.util.Json;
import com.kimo.shop.dao.BasketMapper;
import com.kimo.shop.service.BasketService;
import com.kimo.shop.service.ProductService;
import com.kimo.shop.service.ShopDetailService;
import com.kimo.shop.service.SkuService;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author kimo-taozhouchuan on 2018/10/18.
 */
@Service
@AllArgsConstructor
public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket> implements BasketService {

    private final BasketMapper basketMapper;

    private final CacheManagerUtil cacheManagerUtil;

    private final ApplicationContext applicationContext;

    private final SkuService skuService;

    private final ShopDetailService shopDetailService;

    private final ProductService productService;

    @Override
    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
    public void deleteShopCartItemsByBasketIds(String userId, List<Long> basketIds) {
        basketMapper.deleteShopCartItemsByBasketIds(userId, basketIds);
    }

    @Override
    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
    public void addShopCartItem(ChangeShopCartParam param, String userId) {
        Basket basket = new Basket();
        basket.setBasketCount(param.getCount());
        basket.setBasketDate(new Date());
        basket.setProdId(param.getProdId());
        basket.setShopId(param.getShopId());
        basket.setUserId(userId);
        basket.setSkuId(param.getSkuId());
        basket.setDistributionCardNo(param.getDistributionCardNo());
        basketMapper.insert(basket);
    }

    @Override
    @CacheEvict(cacheNames = "ShopCartItems", key = "#basket.userId")
    public void updateShopCartItem(Basket basket) {
        basketMapper.updateById(basket);
    }

    @Override
    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
    public void deleteAllShopCartItems(String userId) {
        basketMapper.deleteAllShopCartItems(userId);
    }

    @Override
    public List<ShopCartItemDto> getShopCartItems(String userId) {
//        // 在这个类里面要调用这里的缓存信息，并没有使用aop，所以不使用注解
//        List<ShopCartItemDto> shopCartItemDtoList = cacheManagerUtil.getCache("ShopCartItems", userId +'-'+ I18nMessage.getDbLang());
//        if (shopCartItemDtoList != null) {
//            return shopCartItemDtoList;
//        }
        List<ShopCartItemDto> shopCartItemDtoList = basketMapper.getShopCartItems(userId);
        for (ShopCartItemDto shopCartItemDto : shopCartItemDtoList) {
            // 如果为英文，并且英文名称不为空，则使用英文名称
            if(Objects.equals(I18nMessage.getDbLang(),1) && StrUtil.isNotBlank(shopCartItemDto.getProdNameEn())){
                shopCartItemDto.setProdName(shopCartItemDto.getProdNameEn());
            }
            shopCartItemDto.setProductTotalAmount(Arith.mul(shopCartItemDto.getProdCount(), shopCartItemDto.getPrice()));
            // 物流配送信息
            Product.DeliveryModeVO deliveryModeVO = Json.parseObject(shopCartItemDto.getDeliveryMode(), Product.DeliveryModeVO.class);
            // 未开启同城配送
            if (!Objects.equals(1, shopCartItemDto.getShopCityStatus())) {
                deliveryModeVO.setHasCityDelivery(false);
            }
            shopCartItemDto.setDeliveryModeVO(deliveryModeVO);
        }
//        cacheManagerUtil.putCache("ShopCartItems", userId +'-'+ I18nMessage.getDbLang(), shopCartItemDtoList);
        return shopCartItemDtoList;
    }

    @Override
    public List<ShopCartItemDto> getShopCartExpiryItems(String userId) {
        return basketMapper.getShopCartExpiryItems(userId);
    }

    @Override
    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
    public void cleanExpiryProdList(String userId) {
        basketMapper.cleanExpiryProdList(userId);
    }

    @Override
    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
    public void updateBasketByShopCartParam(String userId, List<ShopCartParam> shopCartParams) {
        shopCartParams = shopCartParams.stream().filter(shopCart -> Objects.nonNull(shopCart.getDiscountId())).collect(Collectors.toList());
        basketMapper.updateDiscountItemId(userId, shopCartParams);
    }

    @Override
    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId +'-'+ #lang")
    public void removeShopCartItemsCacheByUserId(String userId, Integer lang) {

    }

    @Override
    public List<String> listUserIdByProdId(Long prodId) {
        return basketMapper.listUserIdByProdId(prodId);
    }

    @Override
    public List<ShopCartDto> getShopCarts(List<ShopCartItemDto> shopCartItems) {
        // 根据店铺ID划分item
        Map<Long, List<ShopCartItemDto>> shopCartMap = shopCartItems.stream().collect(Collectors.groupingBy(ShopCartItemDto::getShopId));

        // 返回一个店铺的所有信息
        List<ShopCartDto> shopCartDtos = Lists.newArrayList();
        for (Long shopId : shopCartMap.keySet()) {

            //获取店铺的所有商品项
            List<ShopCartItemDto> shopCartItemDtoList = shopCartMap.get(shopId);

            // 构建每个店铺的购物车信息
            ShopCartDto shopCart = new ShopCartDto();

            //店铺信息
            shopCart.setShopId(shopId);
            ShopCartItemDto shopCartItemDto = shopCartItemDtoList.get(0);
            shopCart.setShopName(shopCartItemDto.getShopName());
            shopCart.setShopCityStatus(shopCartItemDto.getShopCityStatus());

            applicationContext.publishEvent(new ShopCartEvent(shopCart, shopCartItemDtoList));

            shopCartDtos.add(shopCart);
        }

        return shopCartDtos;
    }

    @Override
    public List<ShopCartItemDto> getShopCartItemsByOrderItems(List<Long> basketId, OrderItemParam orderItem,String userId) {
        if (orderItem == null && CollectionUtil.isEmpty(basketId)) {
            return Collections.emptyList();
        }

        // 当立即购买时，没有提交的订单是没有购物车信息的
        if (CollectionUtil.isEmpty(basketId) && orderItem != null) {

//            Sku sku = skuService.getSkuBySkuId(orderItem.getSkuId());
            Sku sku = skuService.getSkuAndLangBySkuId(orderItem.getSkuId(),I18nMessage.getDbLang());
            if (sku == null) {
                // 订单包含无法识别的商品
                throw new RuntimeException(I18nMessage.getMessage("kimo.order.status.error"));
            }
            Product prod = productService.getProductByProdId(orderItem.getProdId(), I18nMessage.getDbLang());
            if (prod == null) {
                // 订单包含无法识别的商品
                throw new RuntimeException(I18nMessage.getMessage("kimo.order.status.error"));
            }

            // 拿到购物车的所有item
            ShopCartItemDto shopCartItemDto = new ShopCartItemDto();
            shopCartItemDto.setBasketId(-1L);
            shopCartItemDto.setSkuId(orderItem.getSkuId());
            // 商品数量
            shopCartItemDto.setProdCount(orderItem.getProdCount());
            // 商品id
            shopCartItemDto.setProdId(orderItem.getProdId());
            shopCartItemDto.setCategoryId(prod.getCategoryId());
            shopCartItemDto.setPreSellStatus(prod.getPreSellStatus());
            shopCartItemDto.setPreSellTime(prod.getPreSellTime());
            shopCartItemDto.setSkuName(sku.getSkuName());
            if(Objects.equals(prod.getProdType(), ProdType.PROD_TYPE_SCORE.value())){
                shopCartItemDto.setScorePrice(sku.getSkuScore() * orderItem.getProdCount());
            }
            shopCartItemDto.setPic(StrUtil.isBlank(sku.getPic())? prod.getPic() : sku.getPic());
            shopCartItemDto.setProdName(sku.getProdName());
            // 存起中英文
            shopCartItemDto.setProdNameCn(sku.getProdNameCn());
            shopCartItemDto.setProdNameEn(sku.getProdNameEn());
            shopCartItemDto.setProductTotalAmount(Arith.mul(sku.getPrice(),orderItem.getProdCount()));
            shopCartItemDto.setPrice(sku.getPrice());
            shopCartItemDto.setDistributionCardNo(orderItem.getDistributionCardNo());
            shopCartItemDto.setBasketDate(new Date());
            // 物流配送信息
            shopCartItemDto.setDeliveryMode(prod.getDeliveryMode());
            Product.DeliveryModeVO deliveryModeVO = Json.parseObject(shopCartItemDto.getDeliveryMode(), Product.DeliveryModeVO.class);
            shopCartItemDto.setDeliveryModeVO(deliveryModeVO);
            ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(orderItem.getShopId());
            shopCartItemDto.setShopId(shopDetail.getShopId());
            shopCartItemDto.setShopName(shopDetail.getShopName());
            return Collections.singletonList(shopCartItemDto);
        }
        List<ShopCartItemDto> dbShopCartItems = getShopCartItems(userId);

        // 返回购物车选择的商品信息
        return dbShopCartItems
                .stream()
                .filter(shopCartItemDto -> basketId.contains(shopCartItemDto.getBasketId()))
                .collect(Collectors.toList());
    }

    @Override
    public ShopCartItemDto getShopCartItem(OrderItemParam orderItem){
//        Sku sku = skuService.getSkuBySkuId(orderItem.getSkuId(),I18nMessage.getDbLang());
        Sku sku = skuService.getSkuAndLangBySkuId(orderItem.getSkuId(),I18nMessage.getDbLang());
        if (sku == null) {
            // 订单包含无法识别的商品
            throw new RuntimeException("kimo.order.unrecognized.prod");
        }
        Product prod = productService.getProductByProdId(orderItem.getProdId(), I18nMessage.getDbLang());
        if (prod == null) {
            // 订单包含无法识别的商品
            throw new RuntimeException("kimo.order.unrecognized.prod");
        }

        // 拿到购物车的所有item
        ShopCartItemDto shopCartItemDto = new ShopCartItemDto();
        shopCartItemDto.setBasketId(-1L);
        shopCartItemDto.setSkuId(orderItem.getSkuId());
        shopCartItemDto.setProdCount(orderItem.getProdCount());
        shopCartItemDto.setProdId(orderItem.getProdId());
        if(Objects.equals(prod.getProdType(),ProdType.PROD_TYPE_SCORE.value())){
            shopCartItemDto.setScorePrice(sku.getSkuScore() * orderItem.getProdCount());
        }
        shopCartItemDto.setSkuName(sku.getSkuName());
        shopCartItemDto.setCategoryId(prod.getCategoryId());
        shopCartItemDto.setPreSellStatus(prod.getPreSellStatus());
        shopCartItemDto.setPreSellTime(prod.getPreSellTime());
        shopCartItemDto.setPic(StrUtil.isBlank(sku.getPic())? prod.getPic() : sku.getPic());
        shopCartItemDto.setProdName(sku.getProdName());
        // 存起中英文
        shopCartItemDto.setProdNameCn(sku.getProdNameCn());
        shopCartItemDto.setProdNameEn(sku.getProdNameEn());
        shopCartItemDto.setProductTotalAmount(Arith.mul(sku.getPrice(),orderItem.getProdCount()));
        shopCartItemDto.setPrice(sku.getPrice());
        shopCartItemDto.setDistributionCardNo(orderItem.getDistributionCardNo());
        shopCartItemDto.setBasketDate(new Date());
        // 物流配送信息
        shopCartItemDto.setDeliveryMode(prod.getDeliveryMode());
        Product.DeliveryModeVO deliveryModeVO = Json.parseObject(shopCartItemDto.getDeliveryMode(), Product.DeliveryModeVO.class);
        shopCartItemDto.setDeliveryModeVO(deliveryModeVO);
        if(orderItem.getShopId() == 0){
            shopCartItemDto.setShopId(0L);
            shopCartItemDto.setShopName(Constant.PLATFORM_SHOP_NAME);
        }else{
            ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(orderItem.getShopId());
            shopCartItemDto.setShopId(shopDetail.getShopId());
            shopCartItemDto.setShopName(shopDetail.getShopName());
        }
        return shopCartItemDto;
    }
}
